/********************************************************************/
/*          AgbMultiBoot.h                                          */
/*            AGB Multiboot Library Declaration                     */
/*                                                                  */
/*          Copyright (C) 1999-2001 NINTENDO Co.,Ltd.               */
/********************************************************************/
#ifndef _AGB_MULTIBOOT_H
#define _AGB_MULTIBOOT_H

#ifdef __cplusplus
extern "C" {
#endif

#include <AgbTypes.h>


/* Do not change the following constants.     */
#define MULTIBOOT_NCHILD 3              // Maximum number of slaves
#define MULTIBOOT_HEADER_SIZE 0xc0      // Header size
#define MULTIBOOT_SEND_SIZE_MIN 0x100   // Minimum transmission size
#define MULTIBOOT_SEND_SIZE_MAX 0x40000 // Maximum transmission size

// Multiplay Boot Parmater Structure
typedef struct {
  u32 system_work[5];   // Can be rewritten within system call. 
                        // Used with library also.
  u8 handshake_data;    // Handshake data from client
  u8 padding;
  u16 handshake_timeout;   // Handshake timeout check counter
  u8 probe_count;       // If not 0, during client recognition or  
                        // boot program transfer
  u8 client_data[MULTIBOOT_NCHILD]; // Handshake data from client
  u8 palette_data;      // Palette's flashing parameter during load 
                        // for client
  u8 response_bit;      // When high probability that slave  
                        // connected, 4P-2P: d3-d1 is 1.
  u8 client_bit;        // For slave distinguished as client, 
                        // 4P-2P: d3-d1 is 1. 
  u8 reserved1;         // Reserved
  u8 *boot_srcp;        // Boot program start (after header)
  u8 *boot_endp;        // Boot program end pointer
  u8 *masterp;          // Pointer to header referenced and output 
                        // by master
  u8 *reserved2[MULTIBOOT_NCHILD]; // Reserved
  u32 system_work2[4];  // Can be rewritten within system call. 
  u8 sendflag;          // If SC7=1 and during send, not 0
  u8 probe_target_bit;  // If target recognized with client, 
                        // 4P-2P: d3-d1 is 1.
  u8 check_wait;        // Wait frame until recoginition with client
  u8 server_type;       // client recognize method   0= Low Speed
                       //  1= High Speed
} MultiBootParam;

/* Error Code
 * If value returned by MultiBootMain() is not 0, an error listed
 * below has occurred. However, there is no need to have separate error
 * messages for all error code types.
 * "Communication Error. Please check connection. Retry with START."
 * "Turn off power, check connection, and turn on again."
 * "Slave is not connected."
 * "Cannot recognize the slave."
 * ,etc.  Messages easy for the player to understand are good.
 * NO_PROBE_TARGET: When recognizing client all machines returned 
 * abnormal data and there is no target.
 * NO_DLREADY: client did not return a download preparations 
 * possible message.
 * BOOT_FAILURE: MultiBoot() system call returned an error.
 * HANDSHAKE_FAILURE: Failed to do handshake with master which should 
 * occur immediately after boot of slave.
 * (Slave may be in infinite loop, request that power be turned off 
 * and on again.)
 */
#define MULTIBOOT_ERROR_04                0x04
#define MULTIBOOT_ERROR_08                0x08
#define MULTIBOOT_ERROR_0c                0x0c
#define MULTIBOOT_ERROR_40                0x40
#define MULTIBOOT_ERROR_44                0x44
#define MULTIBOOT_ERROR_48                0x48
#define MULTIBOOT_ERROR_4c                0x4c
#define MULTIBOOT_ERROR_80                0x80
#define MULTIBOOT_ERROR_84                0x84
#define MULTIBOOT_ERROR_88                0x88
#define MULTIBOOT_ERROR_8c                0x8c
#define MULTIBOOT_ERROR_NO_PROBE_TARGET   0x50
#define MULTIBOOT_ERROR_NO_DLREADY        0x60
#define MULTIBOOT_ERROR_BOOT_FAILURE      0x70
#define MULTIBOOT_ERROR_HANDSHAKE_FAILURE 0x71

/* After an error, or when a value other than 0xffff is returned,
 * the avoid chattering wait(frames) until redo connection check.
 * The client timeout is about 11 frames so use value sufficiently
 * longer than this.
 * Usually during this time the MASTER_INFO is sent, but when there
 * is a system call error, nothing is sent at this time and it waits.
 * Then, during this time period MASTER_INFO is sent.
 */
#define MULTIBOOT_CONNECTION_CHECK_WAIT 15

/* Recognition of Slave
 * Value set in MultiBootParam structure member server_type 
 * MULTIBOOT_SERVER_TYPE_NORMAL: Slow speed recognition mode
 *   The MultiBootMain() function communicates 2 bytes with one call.
 *   Therefore, processing returns from MultiBootMain() function 
 *   in short time.
 * MULTIBOOT_SERVER_TYPE_QUICK: High speed recognition mode
 *   In MultiBootMain() function as many consecutive communications
 *    are done as possible.
 *   Therefore, processing may not return from MultiBootMain() for 
 *   several dozen frames.
 *   During this time, there is no problem if processing for sound and 
 *   display cannot be done.  If processing for sound and display is 
 *   done with timer interrupt processing, you can use.
 */
#define MULTIBOOT_SERVER_TYPE_NORMAL 0
#define MULTIBOOT_SERVER_TYPE_QUICK  1

/* Timeout for slave's final start up check   400 frames  */
#define MULTIBOOT_HANDSHAKE_TIMEOUT 400

#ifdef __cplusplus
}      /* extern "C" */
#endif

#endif    /* _AGB_MULTIBOOT_H */
/* End of AgbMultiBoot.h */
